package com.scan.converter.controller;


import com.aliyun.oss.OSSClient;
import com.scan.converter.Constants;
import com.scan.converter.domain.ApiResult;

import com.scan.converter.domain.BaseResult;
import com.scan.converter.httpClient.HttpAPIService;
import com.scan.converter.httpClient.HttpResult;
import net.sf.json.JSONObject;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;


/**
 * Created by 李明杰 on 2018/6/21.
 */

@Controller
public class IndexController {
    private static Logger logger = LoggerFactory.getLogger(IndexController.class);
    @Resource
    private HttpAPIService httpAPIService;

    /**
     * 上传图片到files文件夹
     *
     * @param multipartFile
     * @return
     */
    @PostMapping("/upload")
    @ResponseBody
    public BaseResult upload(@RequestParam(value = "firstFile", required = true) MultipartFile multipartFile, String firstSaveName,  String projectName,  String visitName) {
        File txtDirFile = new File("D:\\PotreeConverter\\txtDir");
        if (!txtDirFile.exists())
            txtDirFile.mkdirs();

        logger.error(txtDirFile.getAbsolutePath());
        logger.error(multipartFile.getOriginalFilename());
        logger.error(multipartFile.getSize() + "");
        logger.error("firstSaveName " + firstSaveName);

        logger.error("projectName " + projectName);

        if (StringUtils.isEmpty(projectName)) {
            return new BaseResult("项目名不能为空", BaseResult.FAIL);
        }

        if (StringUtils.isEmpty(visitName)) {
            return new BaseResult("访问名不能为空", BaseResult.FAIL);
        }

        if (StringUtils.isEmpty(firstSaveName)) {
            return new BaseResult("oss保存名不能为空", BaseResult.FAIL);
        }

        File saveFile = new File(txtDirFile, multipartFile.getOriginalFilename());
        if (saveFile.exists())
            saveFile.delete();


        ApiResult apiResult = new ApiResult();

        logger.info(saveFile.getAbsolutePath() + "  ");
        try {
            IOUtils.copy(multipartFile.getInputStream(), new FileOutputStream(saveFile));
            apiResult.msg = "上传成功";
        } catch (IOException e) {
            e.printStackTrace();
            apiResult.code = ApiResult.FAIL;
            apiResult.msg = e.getMessage();
            return apiResult;
        }

        File convertFileDir = null;
        try {
            convertFileDir = convertFile(saveFile, firstSaveName);
            logger.error("转换成功");
            uploadToOss(convertFileDir);
            logger.error("上传成功");


        } catch (Exception e) {
            e.printStackTrace();
            apiResult.code = ApiResult.FAIL;
            apiResult.msg = e.getMessage();
            return apiResult;

        }
        postToServer(visitName,firstSaveName, null,projectName, apiResult);

        return apiResult;
    }

    @PostMapping("/uploadMultipart")
    @ResponseBody
    public BaseResult uploadMultipart(@RequestParam(value = "firstFile", required = true) MultipartFile firstFile, @RequestParam(value = "secondFile", required = true) MultipartFile secondFile, String firstSaveName, String secondSaveName, String projectName, String visitName) {
        File txtDirFile = new File("D:\\PotreeConverter\\txtDir");
        if (!txtDirFile.exists())
            txtDirFile.mkdirs();

        logger.error(txtDirFile.getAbsolutePath());
        logger.error(firstFile.getOriginalFilename());
        logger.error(secondFile.getOriginalFilename());

        logger.error("firstSaveName  " + firstSaveName);
        logger.error("secondSaveName  " + secondSaveName);
        logger.error("projectName " + projectName);

        if (StringUtils.isEmpty(projectName)) {
            return new BaseResult("项目名不能为空", BaseResult.FAIL);
        }

        if (StringUtils.isEmpty(visitName)) {
            return new BaseResult("访问名不能为空", BaseResult.FAIL);
        }

        if (StringUtils.isEmpty(firstSaveName)||StringUtils.isEmpty(secondSaveName)) {
            return new BaseResult("oss保存名不能为空", BaseResult.FAIL);
        }


        File firstSaveFile = new File(txtDirFile, firstFile.getOriginalFilename());
        if (firstSaveFile.exists())
            firstSaveFile.delete();

        File secondSaveFile = new File(txtDirFile, secondFile.getOriginalFilename());
        if (secondSaveFile.exists())
            secondSaveFile.delete();


        ApiResult apiResult = new ApiResult();
//
        logger.info(firstSaveFile.getAbsolutePath() + "  ");
        logger.info(secondSaveFile.getAbsolutePath() + "  ");
        try {
            IOUtils.copy(firstFile.getInputStream(), new FileOutputStream(firstSaveFile));
            IOUtils.copy(secondFile.getInputStream(), new FileOutputStream(secondSaveFile));
            apiResult.msg = "上传成功";
        } catch (IOException e) {
            e.printStackTrace();
            apiResult.code = ApiResult.FAIL;
            apiResult.msg = e.getMessage();
            return apiResult;
        }

        File convertFileDir = null;
        try {
            convertFileDir = convertFile(firstSaveFile, firstSaveName);
            logger.error("firstFile转换成功");
            uploadToOss(convertFileDir);
            logger.error("firstFile上传成功");

            convertFileDir = convertFile(secondSaveFile, secondSaveName);
            logger.error("secondFile转换成功");
            uploadToOss(convertFileDir);
            logger.error("secondFile上传成功");


        } catch (Exception e) {
            e.printStackTrace();
            apiResult.code = ApiResult.FAIL;
            apiResult.msg = e.getMessage();
            return apiResult;

        }
        postToServer(visitName,firstSaveName,secondSaveName, projectName, apiResult);

        return apiResult;
    }

    private void postToServer(String visitName,String firstSaveName, String secondSaveName, String projectName, ApiResult apiResult) {
        try {
            Map<String, Object> map = new HashMap<>();
            map.put("projectName", projectName);
            map.put("visitName", visitName);
            map.put("firstSaveName", firstSaveName);
            map.put("firstUrl", "http://" + Constants.pointCloudBucketName + ".oss-cn-shenzhen.aliyuncs.com/" + firstSaveName + "/pointclouds/pageName/cloud.js");
            if (!StringUtils.isEmpty(secondSaveName)){
                map.put("secondSaveName", secondSaveName);
                map.put("secondUrl", "http://" + Constants.pointCloudBucketName + ".oss-cn-shenzhen.aliyuncs.com/" + secondSaveName + "/pointclouds/pageName/cloud.js");
            }




            HttpResult httpResult = httpAPIService.doPost(Constants.AliYunIP + "/pointcloud/updatePointCloud", map);
//            HttpResult httpResult = httpAPIService.doPost("http://127.0.0.1:8090/updatePointCloud", map);
            logger.info("返回消息 " + httpResult);
            if (httpResult.getCode() == 200) {
                BaseResult baseResult = (BaseResult) JSONObject.toBean(JSONObject.fromObject(httpResult.getBody()), BaseResult.class);
                apiResult.msg = baseResult.msg;
                apiResult.code = baseResult.code;
            } else {
                apiResult.msg = "请求失败";
                apiResult.code = BaseResult.FAIL;
            }
        } catch (Exception e) {
            e.printStackTrace();
            apiResult.msg = "请求失败:" + e.getMessage();
            apiResult.code = BaseResult.FAIL;
        }
    }

    private void uploadToOss(File convertFileDir) throws Exception {
        OSSClient ossClient = new OSSClient(Constants.endpoint, Constants.accessKeyId, Constants.accessKeySecret);

        Collection<File> files = FileUtils.listFiles(convertFileDir, null, true);
        logger.info("点云文件上传 **** 数量：" + files.size() + "  " + convertFileDir.getParentFile().getAbsolutePath());
        File uploadingFile = null;
        try {
            for (File file : files) {
                uploadingFile = file;
                String ossPath = file.getAbsolutePath().substring(convertFileDir.getParentFile().getAbsolutePath().length() + 1).replaceAll("\\\\", "/");
                ossClient.putObject(Constants.pointCloudBucketName, ossPath, file);
                logger.error("上传成功：" + file.getAbsolutePath() + "  " + ossPath);
            }

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("上传失败：" + uploadingFile.getAbsolutePath());
            throw new Exception(e.getMessage() + "****" + uploadingFile.getAbsolutePath());
        } finally {
            ossClient.shutdown();
        }
    }

    private File convertFile(File saveFile, String saveName) throws Exception {
        File pointCloudDir = new File("D:\\PotreeConverter\\pointCloudDir");
        if (!pointCloudDir.exists())
            pointCloudDir.mkdirs();

        File convertFileDir = new File(pointCloudDir, saveName);
        try {
            Process process = Runtime.getRuntime().exec("D:\\PotreeConverter\\PotreeConverter.exe " + saveFile.getAbsolutePath() + " -o " + convertFileDir.getAbsolutePath() + "\\pointclouds\\pageName -f xyzrgb --overwrite");
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = "";
            while ((line = bufferedReader.readLine()) != null) {
                logger.error(line);
            }
            int exitValue = process.waitFor();
            if (exitValue != 0)
                throw new RuntimeException("exitValue!=0");

        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception(e);
        }
        return convertFileDir;

    }

    @GetMapping("/uploadPointCloud")
    public String uploadPointCloud(Model model) {
        logger.info("uploadPointCloud");
        return "uploadPointCloud";
    }

    @GetMapping("/main")
    public String main(Model model) {
        return "/main";
    }

    @GetMapping("/index")
    public String index(Model model) {
        return "/index";
    }

    @GetMapping("/pointcloudList")
    public String pointcloudList(Model model) {
        return "/pointcloudList";
    }


}
